package com.ds.infra.rpc.core.transport.codec;

import com.ds.infra.rpc.core.protocol.RpcProtocol;
import com.ds.infra.rpc.core.serializer.SerializerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteOrder;

/**
 * 通用RPC协议编码器（处理所有出站消息）
 * 泛型T支持：RpcRequest / RpcResponse
 *
 * @author WeiShaoying
 */
@Slf4j
@ChannelHandler.Sharable
public class RpcEncoder<T> extends MessageToByteEncoder<RpcProtocol<T>> {

    private final Class<T> genericClass;

    public RpcEncoder(Class<T> genericClass) {
        this.genericClass = genericClass;
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, RpcProtocol<T> protocol, ByteBuf out) {
        try {
            // 1. 序列化消息体
            byte[] bodyBytes = SerializerFactory.serialize(protocol.getBody());

            // 2. 写入协议头（大端序）
            out.order(ByteOrder.BIG_ENDIAN)
                    .writeShort(protocol.getHeader().getMagic())
                    .writeByte(protocol.getHeader().getVersion())
                    .writeByte(protocol.getHeader().getMsgType())
                    .writeInt(bodyBytes.length);

            // 3. 写入消息体
            out.writeBytes(bodyBytes);
        } catch (Exception e) {
            log.error("Encode error", e);
            throw new RuntimeException(e);
        }
    }
}
